#include "condition.hpp"
#include "tools.hpp"

namespace thread
{
	Condition::Condition()
	{
		int ret = 0;
		if ((ret = ::pthread_cond_init(&_cond, 0)) != 0)
		{
			tools::LOG_ERR_MSG(ret, "Condition::Condition pthread_cond_init error");
		}
	}

	Condition::~Condition()
	{
		int ret = 0;
		if ((ret = ::pthread_cond_destroy(&_cond)) != 0)
		{
			tools::LOG_ERR_MSG(ret, "Condition::~Condition pthread_cond_destroy error");
		}
	}

	void Condition::wait(Lock & lock)
	{
		int ret = 0;
		if ((ret = ::pthread_cond_wait(&_cond, &lock._mutex)) != 0)
		{
			tools::LOG_ERR_MSG(ret, "Condition::wait pthread_cond_wait error");
		}
	}

	bool Condition::wait(Lock & lock, long ms)
	{
		struct timespec spec;
		tools::get_abs_timespec(ms, spec);

		int ret = ::pthread_cond_timedwait(&_cond, &lock._mutex, &spec);

		if (ETIMEDOUT == ret)
		{
			return false;
		}

		if (0 != ret)
		{
			tools::LOG_ERR_MSG(ret, "Condition::wait(long ms) pthread_cond_timewait error");
		}

		return (0 == ret);
	}

	void Condition::signal()
	{
		int ret = 0;
		if ((ret = ::pthread_cond_signal(&_cond)) != 0)
		{
			tools::LOG_ERR_MSG(ret, "Condition::signal pthread_cond_signal error");
		}
	}

	void Condition::brocast()
	{
		int ret = 0;
		if ((ret = ::pthread_cond_broadcast(&_cond)) != 0)
		{
			tools::LOG_ERR_MSG(ret, "Condition::brocast pthread_cond_brocast error");
		}
	}
}

